import socket
import struct
from cryptography.fernet import Fernet
import json
import threading
import time
import os
class PcInfoCastC:
    def __init__(self):
        MCAST_GRP = '224.1.1.1' # 组播地址
        MCAST_PORT = 50050 # 端口号
        self.ip_list = []
        self.user_name_list = []
        self.last_update_time_list = []
        # self.is_alive = True
        with open("key", "rb") as f:
           self.key = f.read()

        # 创建 UDP 套接字
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
        # 绑定到组播地址和端口号
        self.sock.bind(("", MCAST_PORT))

        # 加入组播组
        mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)
        self.sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)

        t = threading.Thread(target=self.listen_net_cast)
        t.start()
        
    def decrypt(self,key, s):
        cipher = Fernet(key)
        return cipher.decrypt(s.encode()).decode()
    def listen_net_cast(self):
        while True:
            data, addr = self.sock.recvfrom(1024)
            data_de = self.decrypt(self.key,data.decode())
            data_dict = json.loads(data_de)
            # for i in data_dict:
            #     print(i,data_dict[i])
            if(data_dict["self_ip"] not in self.ip_list):
                print("registration: ip {} ,user_name {}".format(data_dict["self_ip"],data_dict["user_name"]))
                self.ip_list.append(data_dict["self_ip"])
                self.user_name_list.append(data_dict["user_name"])
                self.last_update_time_list.append(time.time())
            else:
                index = self.ip_list.index(data_dict["self_ip"])
                self.last_update_time_list[index] = time.time()


            # print("listen_once")
 





print("welcome to BPCI client")
pc_info_cast_client = PcInfoCastC()

# 接收数据报
while True:
    cmd = input(">>>")
    if(cmd == "list"):
        print("online device")
        print("ip           |  user name | last update time")
        for i in range(len(pc_info_cast_client.ip_list)):
            last_update_time = int(time.time() - pc_info_cast_client.last_update_time_list[i])
            print("{} | {}      | {} seconds ago".format(pc_info_cast_client.ip_list[i],pc_info_cast_client.user_name_list[i],last_update_time)) 
    elif(cmd == "help"):
        print("you can input :")  
        print("list")
    elif(cmd == "exit"):
        print("please enter ctrl+c to exit")  
        break
    else:
        print("command '%s'is unsupport"%cmd)